package com.framework.admin.service.impl;

import com.framework.admin.model.*;
import com.framework.admin.repository.SysCompanyRepository;
import com.framework.admin.repository.SysDeptRepository;
import com.framework.admin.repository.SysUserRoleRepository;
import com.framework.admin.repository.UserRepository;
import com.framework.admin.domain.param.CompanyPwdParam;
import com.framework.admin.domain.param.CompanyRegisterParam;
import com.framework.admin.enums.DeptEnums;
import com.framework.admin.enums.UserEnums;
import com.framework.admin.service.IRegisterService;
import com.framework.admin.service.IRoleService;
import com.framework.admin.util.Constant;
import com.framework.admin.util.StringFormatUtils;
import com.framework.common.constant.ErrorCode;
import com.framework.common.exception.BusinessException;
import com.framework.common.util.RSAEncrypt;
import com.framework.common.util.RedisUtil;
import com.framework.common.util.email.EmailSupport;
import com.framework.common.util.email.SpringEmailSupport;
import com.framework.common.util.email.ToEmail;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.UUID;

@Service
public class RegisterService implements IRegisterService {

    @Autowired
    private SysCompanyRepository sysCompanyRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${front.url:}")
    private String fronUrl;
    @Value("${login.privateKey:}")
    private String privateKey;
    @Autowired
    private IRoleService roleService;
    @Autowired
    SysDeptRepository sysDeptRepository;
    @Autowired
    private SysUserRoleRepository sysUserRoleRepository;

    @Override
    public void insertCompany(CompanyRegisterParam param) {
        SysUser accountSysUser = userRepository.findByAccount(param.getAccount());
        Optional.ofNullable(accountSysUser).ifPresent(t -> {
            throw new BusinessException("账号已存在");
        });

        //company
        SysCompany company = new SysCompany();
        company.setSimplename(param.getFullname());
        company.setFullname(param.getFullname());
        company.setCompanyType(param.getType());
        company.setCompanyRegion(param.getRegion());
        sysCompanyRepository.save(company);

        //dept
        SysDept sysDept = new SysDept();
        sysDept.setFullName(param.getFullname());
        sysDept.setSimpleName(param.getFullname());
        sysDept.setPid(Constant.ROOT);
        sysDept.setStatus(DeptEnums.StatusEnum.ENABLE.getValue());
        sysDept.setType(DeptEnums.TypeEnum.DEPT.getValue());
        sysDeptRepository.save(sysDept);

        //user
        SysUser user = new SysUser();
        user.setAccount(param.getAccount());
        user.setName(param.getName());
        user.setEmail(param.getEmail());
        user.setStatus(UserEnums.StatusEnum.FROZEN.getValue());
        user.setDeptId(sysDept.getId());

        //role
        SysRole sysRole = new SysRole();
        sysRole.setName(param.getFullname());
        sysRole.setRemark(String.format(StringFormatUtils.DEFAULT_COMPANY_ROLE_NAME, param.getFullname()));
        sysRole.setPid(Constant.ROOT);
        sysRole.setIsAdmin(0);
        sysRole = roleService.save(sysRole);
        user = userRepository.save(user);

        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(sysRole.getId());
        userRole.setUserId(user.getId());
        sysUserRoleRepository.save(userRole);

        //生成验证码
        String verifyCode = UUID.randomUUID().toString();
        //发邮箱，确认按钮链接带验证码
        EmailSupport emailSupport = SpringEmailSupport.getInstance();
        emailSupport.htmlEmail(toEmail(param.getEmail(), verifyCode));

        redisUtil.set(Constant.REDIS_USER_REGISTER_CODE_KEY + verifyCode, user.getId(), 3600L);
    }


    @Override
    public void updatePwd(CompanyPwdParam param) throws Exception {
        String key = Constant.REDIS_USER_REGISTER_CODE_KEY + param.getVerifyCode();
        String userId = redisUtil.get(key);
        if (StringUtils.isEmpty(userId)) {
            throw new BusinessException(ErrorCode.Login.vilidateCodeTimeout);
        }

		if (StringUtils.isEmpty(param.getPwd())) {
			throw new BusinessException(ErrorCode.Login.vilidateCodeTimeout);
		}

        //rsa密码解密,密码是否一致
        String pwd = RSAEncrypt.decrypt(param.getPwd(), privateKey);
        String confirmPwd = RSAEncrypt.decrypt(param.getConfirmPwd(), privateKey);

        if (!pwd.equals(confirmPwd)) {
            throw new BusinessException("确认密码不一致!");
        }

        SysUser sysUser = userRepository.findOne(userId);
        if (ObjectUtils.isEmpty(sysUser)) {
            throw new BusinessException("用户不存在");
        }
        //密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		String encodePassword = passwordEncoder.encode(pwd);
        sysUser.setPassword(encodePassword);
        sysUser.setStatus(UserEnums.StatusEnum.ENABLE.getValue());
        userRepository.save(sysUser);

        redisUtil.del(key);
    }

    private ToEmail toEmail(String email, String verifyCode) {
        ToEmail toEmail = new ToEmail();
        toEmail.setTos(new String[]{email});
        toEmail.setSubject(Constant.USER_REGISTER_EMAIL_SUBJECT);

        //点击链接跳转前端页面
        toEmail.setContent(String.format(
                StringFormatUtils.USER_REGISTER_EMAIL_CONTENT_TEMPLATE,
                fronUrl,
                verifyCode)
        );


        return toEmail;
    }

}
